﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Topro.Util
{
    public class CalaSteelPlateUtil
    {
        public CalaSteelPlateUtil()
        {
            UpSteelPlateNums = 0;
            DownSteelPlateNums = 0;
        }
        public CalaSteelPlateUtil(uint uSteelPlate)
        {
            UpSteelPlateNums = uSteelPlate;
            DownSteelPlateNums = uSteelPlate;
        }
        public uint BookNums = 0;
        public uint CrossFlag = 0;  //是否包含切片的book 
        public uint CrashPadType = 1; //缓冲垫放置类型
        public uint FullFlag = 0;   //是否整板
        public uint CrossPlate = 0;    //切片数量
        public uint CommPlate = 0;   //普通板数
        public uint UpSteelPlateNums = 1; //上钢板 有切片的为3
        public uint DownSteelPlateNums = 1; //下钢板 有切片时数量为3
        public uint SupplementSteelPlateNums = 0; //补钢板数量

    }
    public class CalcFormula
    {
        public string sLayer_type = "";   //叠合结构
        public int iCrashPadFlag = 0;  //缓存垫结构 0 没有 1中间一张 2 上下一张 3 上中下各一张
        public string sAllNormalHeight = string.Empty; //全普通板高度公式
        public string sAllNormalMaxPiec = string.Empty; //普通板最多放多少片
        public string sAllSliceMaxPiec = string.Empty; //全切片最多放多少片
        public string sMixHeight = string.Empty; //混合放求高度公式 只能求高度
        public string sHaveCrossNumCanLoadMaxNormalPiecNum = string.Empty; //已知切片板求 最大能装载多少片普通板
    }
    public class UpAndDownSteelNum
    {
        public int iUpSteelNum;
        public int iDownSteelNum;
    }

    public class CalcSteelPlateNew
    {

        public CalcSteelPlateNew()
        {
            AddCountFormula();
        }
        public CalaSteelPlateUtil BookFullNoCross = new CalaSteelPlateUtil(1);
        public CalaSteelPlateUtil BookNoFullNoCross = new CalaSteelPlateUtil(1);
        public CalaSteelPlateUtil BookFullOnlyCross = new CalaSteelPlateUtil(2);
        public CalaSteelPlateUtil BookNoFullMixCross = new CalaSteelPlateUtil(2);
        public static Dictionary<string, CalcFormula> m_DitCalcFormula = null;
        public static Dictionary<string, UpAndDownSteelNum> m_DitUpDownSteelPlateInfo = null;
        string m_sLogName = "CalcBookLog";

        private int IniSteelInfo(string sLayerRecipe)
        {
            int iRet = 0;
            if (sLayerRecipe == "LA1" || sLayerRecipe == "LA2" || sLayerRecipe == "LA4" || sLayerRecipe == "LA5" || sLayerRecipe == "LA6" || sLayerRecipe == "LA9")
            {
                BookFullNoCross.UpSteelPlateNums = 0;
                BookFullNoCross.DownSteelPlateNums = 0;

                BookNoFullNoCross.UpSteelPlateNums = 0;
                BookNoFullNoCross.DownSteelPlateNums = 0;

                BookNoFullMixCross.UpSteelPlateNums = 1;
                BookNoFullMixCross.DownSteelPlateNums = 1;

                BookFullOnlyCross.UpSteelPlateNums = 2;
                BookFullOnlyCross.DownSteelPlateNums = 1;

            }
            else if (sLayerRecipe == "LA3" || sLayerRecipe == "LA7")
            {
                BookFullNoCross.UpSteelPlateNums = 1;
                BookFullNoCross.DownSteelPlateNums = 0;

                BookNoFullNoCross.UpSteelPlateNums = 1;
                BookNoFullNoCross.DownSteelPlateNums = 0;

                BookNoFullMixCross.UpSteelPlateNums = 1;
                BookNoFullMixCross.DownSteelPlateNums = 2;

                BookFullOnlyCross.UpSteelPlateNums = 3;
                BookFullOnlyCross.DownSteelPlateNums = 2;
            }
            else if (sLayerRecipe == "LA8")
            {
                BookFullNoCross.UpSteelPlateNums = 1;
                BookFullNoCross.DownSteelPlateNums = 0;

                BookNoFullNoCross.UpSteelPlateNums = 1;
                BookNoFullNoCross.DownSteelPlateNums = 0;

                BookNoFullMixCross.UpSteelPlateNums = 1;
                BookNoFullMixCross.DownSteelPlateNums = 2;

                BookFullOnlyCross.UpSteelPlateNums = 3;
                BookFullOnlyCross.DownSteelPlateNums = 2;
            }
            else if (sLayerRecipe == "LA10")
            {
                BookFullNoCross.UpSteelPlateNums = 0;
                BookFullNoCross.DownSteelPlateNums = 0;

                BookNoFullNoCross.UpSteelPlateNums = 0;
                BookNoFullNoCross.DownSteelPlateNums = 0;

                BookNoFullMixCross.UpSteelPlateNums = 0;
                BookNoFullMixCross.DownSteelPlateNums = 1;

                BookFullOnlyCross.UpSteelPlateNums = 2;
                BookFullOnlyCross.DownSteelPlateNums = 1;
            }
            else if (sLayerRecipe == "LA11")
            {
                BookFullNoCross.UpSteelPlateNums = 1;
                BookFullNoCross.DownSteelPlateNums = 0;

                BookNoFullNoCross.UpSteelPlateNums = 1;
                BookNoFullNoCross.DownSteelPlateNums = 0;

                BookNoFullMixCross.UpSteelPlateNums = 1;
                BookNoFullMixCross.DownSteelPlateNums = 2;

                BookFullOnlyCross.UpSteelPlateNums = 3;
                BookFullOnlyCross.DownSteelPlateNums = 2;
            }
            else if (sLayerRecipe == "LA12")
            {
                //
                BookFullNoCross.UpSteelPlateNums = 0;           //9302
                BookFullNoCross.DownSteelPlateNums = 0;         //9303

                BookNoFullNoCross.UpSteelPlateNums = 0;         //D9306
                BookNoFullNoCross.DownSteelPlateNums = 0;       //D9307

                BookNoFullMixCross.UpSteelPlateNums = 0;        //D9312
                BookNoFullMixCross.DownSteelPlateNums = 1;      //D9313

                BookFullOnlyCross.UpSteelPlateNums = 0;         //D9317
                BookFullOnlyCross.DownSteelPlateNums = 1;       //D9318
            }
            else if (sLayerRecipe == "LA13")
            {
                BookFullNoCross.UpSteelPlateNums = 0;
                BookFullNoCross.DownSteelPlateNums = 0;

                BookNoFullNoCross.UpSteelPlateNums = 0;
                BookNoFullNoCross.DownSteelPlateNums = 0;

                BookNoFullMixCross.UpSteelPlateNums = 0;
                BookNoFullMixCross.DownSteelPlateNums = 1;

                BookFullOnlyCross.UpSteelPlateNums = 0;
                BookFullOnlyCross.DownSteelPlateNums = 1;
            }
            else if (sLayerRecipe == "LA19")
            {
                BookFullNoCross.UpSteelPlateNums = 0;
                BookFullNoCross.DownSteelPlateNums = 0;

                BookNoFullNoCross.UpSteelPlateNums = 0;
                BookNoFullNoCross.DownSteelPlateNums = 0;

                BookNoFullMixCross.UpSteelPlateNums = 0;
                BookNoFullMixCross.DownSteelPlateNums = 1;

                BookFullOnlyCross.UpSteelPlateNums = 0;
                BookFullOnlyCross.DownSteelPlateNums = 1;
            }
            else if (sLayerRecipe == "LA20")
            {
                BookFullNoCross.UpSteelPlateNums = 0;
                BookFullNoCross.DownSteelPlateNums = 0;

                BookNoFullNoCross.UpSteelPlateNums = 0;
                BookNoFullNoCross.DownSteelPlateNums = 0;

                BookNoFullMixCross.UpSteelPlateNums = 0;
                BookNoFullMixCross.DownSteelPlateNums = 1;

                BookFullOnlyCross.UpSteelPlateNums = 0;
                BookFullOnlyCross.DownSteelPlateNums = 1;
            }

            return iRet;
        }
        private uint GetStandBookPlates(string sProductNo, string sLayer)
        {
            uint uiStandPlates = 30; //默认为30

            //switch (sLayer)
            //{
            //    case "BU01":
            //        uiStandPlates = 30;
            //        break;
            //    case "BU02":
            //    case "BU03":
            //    case "BU04":
            //    case "BU05":
            //    case "EP":
            //        uiStandPlates = 25;
            //        break;
            //    case "ODP":
            //        uiStandPlates = 20;
            //        break;


            //}
            return uiStandPlates;
        }
        private static void AddCountFormula()
        {
            m_DitCalcFormula = new Dictionary<string, CalcFormula>();

            CalcFormula layerFormulaLA1 = new CalcFormula();
            layerFormulaLA1.sLayer_type = "LA1";
            layerFormulaLA1.sAllNormalHeight = "{1}*({0}+1.5)+1.5";  //普通板厚度  板厚;普通板片数;切片数
            layerFormulaLA1.sMixHeight = "1.5*2+{2}*({0}+1.5*3)+{1}*(1.5+{0})"; //1.5*2+(板厚+1.5*3)*切片数量+(板厚+1.5)*普通板数量 ; 板厚;普通板片数;切片数
            layerFormulaLA1.sAllSliceMaxPiec = "({0}-1.5*2)/({1}+3*1.5)"; //纯切片板最高高度  限高高度; 板厚
            layerFormulaLA1.sAllNormalMaxPiec = "({0}-1.5)/({1}+1.5)"; //普通板最高板数量   ;限高高度; 板厚
            layerFormulaLA1.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-(1.5*2+{2}*({1}+1.5*3)))/(1.5+{1})"; //限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA1", layerFormulaLA1);
            CalcFormula layerFormulaLA2 = new CalcFormula();
            layerFormulaLA2.sLayer_type = "LA2";
            layerFormulaLA2.sAllNormalHeight = "{1}*({0}+1.5)+1.5";  //普通板厚度  板厚;普通板片数;切片数
            layerFormulaLA2.sMixHeight = "1.5*2+{2}*({0}+1.5*3)+{1}*(1.5+{0})"; //1.5*2+(板厚+1.5*3)*切片数量+(板厚+1.5)*普通板数量 ; 板厚;普通板片数;切片数
            layerFormulaLA2.sAllSliceMaxPiec = "({0}-1.5*2)/({1}+3*1.5)"; //纯切片板最高高度  限高高度; 板厚
            layerFormulaLA2.sAllNormalMaxPiec = "({0}-1.5)/({1}+1.5)"; //普通板最高板数量   ;限高高度; 板厚
            layerFormulaLA2.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-(1.5*2+{2}*({1}+1.5*3)))/(1.5+{1})"; //限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA2", layerFormulaLA2);

            CalcFormula layerFormulaLA7 = new CalcFormula();
            layerFormulaLA7.sLayer_type = "LA7";
            layerFormulaLA7.sAllNormalHeight = "(0.5+{0})*{1}+(0.5+1.5)";//普通板厚度  板厚;普通板片数;切1片数
            layerFormulaLA7.sMixHeight = "1.5*2+(0.5*2+{0}+1.5*3)*{2}+(0.5+{0})*{1}+1.5+0.5"; //混合板厚度  板厚;普通板片数;切片数
            layerFormulaLA7.sAllSliceMaxPiec = "({0}-1.5*2)/(0.5*2+{1}+1.5*3)";//纯切片板最高高度  限高高度; 板厚
            layerFormulaLA7.sAllNormalMaxPiec = "({0}-1.5-0.5)/(0.5+{1})"; //纯切片板最高高度  限高高度; 板厚
            layerFormulaLA7.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-(1.5*2+{2}*({1}+1.5*3))-1.5-0.5)/(0.5+{1})";//限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA7", layerFormulaLA7);

            CalcFormula layerFormulaLA8 = new CalcFormula();
            layerFormulaLA8.sLayer_type = "LA8";
            layerFormulaLA8.sAllNormalHeight = "(0.5*2+{0}+1.5)*{1}";//普通板厚度  板厚;普通板片数;切1片数
            layerFormulaLA8.sMixHeight = "1.5*2+(0.5*2+{0}+1.5*3)*{2}+(0.5*2+{0}+1.5)*{1}"; //混合板厚度  板厚;普通板片数;切片数
            layerFormulaLA8.sAllSliceMaxPiec = "({0}-1.5*2)/(0.5*2+{1}+1.5*3)";//纯切片板最高高度  限高高度; 板厚
            layerFormulaLA8.sAllNormalMaxPiec = "{0}/((0.5*2+{1}+1.5))"; //纯普通板最高高度  限高高度; 板厚
            layerFormulaLA8.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-(1.5*2+{2}*(2*0.5+{1}+1.5*3)))/(0.5*2+{1}+1.5)";//限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA8", layerFormulaLA8);

            CalcFormula layerFormulaLA10 = new CalcFormula();
            layerFormulaLA10.sLayer_type = "LA10";
            layerFormulaLA10.sAllNormalHeight = "(1.5+1.5+0.00001)+(1.5+{0})*{1}";//普通板厚度  板厚;普通板片数;切1片数
            layerFormulaLA10.sMixHeight = "1.5*2+({0}+1.5*3)*{2}+1.5+0.00001+({0}+1.5)*{1}"; //混合板厚度  板厚;普通板片数;切片数 1.5*2+(板厚+1.5*3)*切片+1.5+0.24+(板厚+1.5)*普通板片数
            layerFormulaLA10.sAllSliceMaxPiec = "({0}-1.5*2-0.00001-1.5)/({1}+1.5*3)";//纯切片板最高高度  限高高度; 板厚
            layerFormulaLA10.sAllNormalMaxPiec = "({0}-(1.5*2+0.00001))/(1.5+{1})"; //纯切片板最高高度  限高高度; 板厚
            layerFormulaLA10.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-1.5-0.00001-(1.5*2+({1}+1.5*3)*{2}))/({1}+1.5)";//限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA10", layerFormulaLA10);

            CalcFormula layerFormulaLA11 = new CalcFormula();
            layerFormulaLA11.sLayer_type = "LA11";
            layerFormulaLA11.sAllNormalHeight = "(0.5+{0})*{1}+1.5*2+0.00001+1.5+0.5+0.5";//普通板厚度  板厚;普通板片数;切1片数
            layerFormulaLA11.sMixHeight = "1.5*2+({0}+0.5*2+1.5*3)*{2}+1.5*2+0.00001+(0.5+{0})*{1}+0.5+1.5+0.5"; //混合板厚度  板厚;普通板片数;切片数 缓冲垫在切片中间会少2mm 
                                                                                                                 //  layerFormulaLA11.sMixHeightCrashPadOutSlice = "1.5*2+({0}+0.5*2+1.5*3)*{2}+1.5*2+0.24+(0.5+{0})*{1}+0.5+1.5+0.5"; //混合板二种高度  未贴合切片
            layerFormulaLA11.sAllSliceMaxPiec = "({0}-1.5*2-0.00001-1.5)/({1}+0.5*2+1.5*3)";//(限高-1.5*2-0.24-1.5)/(板厚+0.5*2+1.5*3) 纯切片板最高高度  限高高度; 板厚
            layerFormulaLA11.sAllNormalMaxPiec = "({0}-(1.5*2+0.00001+1.5+0.5+0.5))/({1}+0.5)";//S（限高-(1.5*2+0.24+1.5+0.5+0.5)) /(板厚度+0.5) 限高高度; 板厚
            layerFormulaLA11.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-(1.5*2+({1}+0.5*2+1.5*3)*{2}+1.5*2+0.00001+0.5+1.5+0.5))/(0.5+{1})";//限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA11", layerFormulaLA11);

            CalcFormula layerFormulaLA12 = new CalcFormula();
            layerFormulaLA12.sLayer_type = "LA12";
            layerFormulaLA12.sAllNormalHeight = "1.5+0.00001+({0}+0.5)*{1}+(1.5*2+0.00001)*2+0.5*2";//普通板厚度  板厚;普通板片数;切1片数
            layerFormulaLA12.sMixHeight = "1.5*2+0.00001+({0}+0.5*2+1.5*3)*{2}+({0}+0.5)*{1}+(1.5+0.00001)*2+0.5*2"; //混合板厚度  板厚;普通板片数;切片数 缓冲垫在切片中间会少2mm 
                                                                                                                     //  layerFormulaLA11.sMixHeightCrashPadOutSlice = "1.5*2+({0}+0.5*2+1.5*3)*{2}+1.5*2+0.24+(0.5+{0})*{1}+0.5+1.5+0.5"; //混合板二种高度  未贴合切片
            layerFormulaLA12.sAllSliceMaxPiec = "({0}-1.5*2-0.00001-(0.00001+1.5)*2)/({1}+0.5*2+1.5*3)";//(限高-1.5*2-0.24-1.5)/(板厚+0.5*2+1.5*3) 纯切片板最高高度  限高高度; 板厚
            layerFormulaLA12.sAllNormalMaxPiec = "({0}-((1.5*2+0.00001)*2+0.5*2+1.5+0.00001))/({1}+0.5)";//S（限高-(1.5*2+0.24+1.5+0.5+0.5)) /(板厚度+0.5) 限高高度; 板厚
            layerFormulaLA12.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-((1.5+0.00001)*2+0.5*2+1.5*2+0.00001+({1}+0.5*2+1.5*3)*{2}))/(0.5+{1})";//限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA12", layerFormulaLA12);

            CalcFormula layerFormulaLA13 = new CalcFormula();
            layerFormulaLA13.sLayer_type = "LA13";
            layerFormulaLA13.sAllNormalHeight = "1.5+0.00001+(0.5+{0})*{1}+(1.5*2+0.00001)+0.5";//普通板厚度  板厚;普通板片数;切片数
            layerFormulaLA13.sMixHeight = "1.5*2+0.00001+({0}+0.5*2+1.5*3)*{2}+({0}+0.5)*{1}+(1.5*2+0.00001)+0.5"; //混合板厚度  板厚;普通板片数;切片数 缓冲垫在切片中间会少2mm 
                                                                                                                   //  layerFormulaLA11.sMixHeightCrashPadOutSlice = "1.5*2+({0}+0.5*2+1.5*3)*{2}+1.5*2+0.24+(0.5+{0})*{1}+0.5+1.5+0.5"; //混合板二种高度  未贴合切片
            layerFormulaLA13.sAllSliceMaxPiec = "({0}-1.5*2-0.00001-(0.00001+1.5))/({1}+0.5*2+1.5*3)";//(限高-1.5*2-0.24-1.5)/(板厚+0.5*2+1.5*3) 纯切片板最高高度  限高高度; 板厚
            layerFormulaLA13.sAllNormalMaxPiec = "({0}-((1.5*2+0.00001)+0.5+1.5+0.00001))/({1}+0.5)";//S（限高-(1.5*2+0.24+1.5+0.5+0.5)) /(板厚度+0.5) 限高高度; 板厚
            layerFormulaLA13.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-(1.5*2+0.00001+({1}+0.5*2+1.5*3)*{2}+(1.5*2+0.00001)+0.5))/(0.5+{1})";//限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA13", layerFormulaLA13);


            CalcFormula layerFormulaLA19 = new CalcFormula();
            layerFormulaLA19.sLayer_type = "LA19";
            layerFormulaLA19.sAllNormalHeight = "1.5+0.00001+(0.5*2+{0}+1.5)*{1}+(1.5+0.00001)*2";//普通板厚度  板厚;普通板片数;切片数
            layerFormulaLA19.sMixHeight = "1.5*2+0.00001+({0}+0.5*2+1.5*3)*{2}+({0}+0.5*2+1.5)*{1}+(1.5+0.00001)*2"; //混合板厚度  板厚;普通板片数;切片数 缓冲垫在切片中间会少2mm 
                                                                                                                     //  layerFormulaLA11.sMixHeightCrashPadOutSlice = "1.5*2+({0}+0.5*2+1.5*3)*{2}+1.5*2+0.24+(0.5+{0})*{1}+0.5+1.5+0.5"; //混合板二种高度  未贴合切片
            layerFormulaLA19.sAllSliceMaxPiec = "({0}-1.5*2-0.00001-(0.00001+1.5)*2)/({1}+0.5*2+1.5*3)";//(限高-1.5*2-0.24-1.5)/(板厚+0.5*2+1.5*3) 纯切片板最高高度  限高高度; 板厚
            layerFormulaLA19.sAllNormalMaxPiec = "({0}-((1.5+0.00001)*2+1.5+0.00001))/({1}+0.5*2+1.5)";//S（限高-(1.5*2+0.24+1.5+0.5+0.5)) /(板厚度+0.5) 限高高度; 板厚
            layerFormulaLA19.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-(1.5*2+0.00001+({1}+0.5*2+1.5*3)*{2}+(1.5*2+0.00001)*2))/(0.5*2+{1})";//限高高度;板厚度;切片数量
            m_DitCalcFormula.Add("LA19", layerFormulaLA19);

            //LA20
            CalcFormula layerFormulaLA20 = new CalcFormula();
            layerFormulaLA20.sLayer_type = "LA20";
            layerFormulaLA20.sAllNormalHeight = "1.5*2+0.00001 +(0.5+0.00001)*3+(0.5+{0})*{1}+0.5+(1.5*2+0.00001)";//普通板厚度  板厚;普通板片数;切片数
            layerFormulaLA20.sMixHeight = "1.5*2+0.00001+(0.5*2 +0.00001+{0}+1.5*3)*{2}+(0.5+0.00001)*2+((0.5+{0})*{1}+0.5+(1.5*2+0.00001)"; //混合板厚度  板厚;普通板片数;切片数 缓冲垫在切片中间会少2mm 
            layerFormulaLA20.sAllSliceMaxPiec = "({0}-1.5*2-0.00001-(0.00001+1.5))/({1}+0.5*2+1.5*3)";//(限高-1.5*2-0.24-1.5)/(板厚+0.5*2+1.5*3) 纯切片板最高高度  限高高度; 板厚
            layerFormulaLA20.sAllNormalMaxPiec = "({0}-((1.5*2+0.00001)*2)-(0.5+0.00001)*3-0.5)/({1}+0.5)";//S 普通板最高叠多少片
            layerFormulaLA20.sHaveCrossNumCanLoadMaxNormalPiecNum = "({0}-(1.5*2+0.00001+(0.5+0.00001)*2+0.5+({1}+0.5*2+0.00001+1.5*3)*{2}+(1.5*2+0.00001)))/(0.5+{1})";//限高高度;板厚度;切片数量


            m_DitCalcFormula.Add("LA20", layerFormulaLA20);

        }
        /// <summary>
        /// 计算混合板子的高度值
        /// </summary>
        /// <param name="sFormula"></param>
        /// <param name="fProductThick"></param>
        /// <param name="uNormalPlatePies"></param>
        /// <param name="uCrossPlateNums"></param>
        /// <returns></returns>
        private float GetMixHeight(string sFormula, float fProductThick, uint uNormalPlatePies, uint uCrossPlateNums)
        {
            float fHeight = 0f;
            try
            {
                string sCalcFormulaWithValue = string.Format(sFormula, fProductThick, uNormalPlatePies, uCrossPlateNums); //板厚 和限高 算普通板最高叠放片数
                object result = new DataTable().Compute(sCalcFormulaWithValue, "");
                fHeight = float.Parse(result.ToString()); //取混合板高度
            }
            catch (Exception ex)
            {

                fHeight = 0f;
            }
            return fHeight;
        }
        private float GetAllNormalProductHeight(string sFormula, float fProductThick, uint uNormalPlatePies)
        {
            float fHeight = 0f;
            try
            {
                string sCalcFormulaWithValue = string.Format(sFormula, fProductThick, uNormalPlatePies); //板厚 和限高 算普通板最高叠放片数
                object result = new DataTable().Compute(sCalcFormulaWithValue, "");
                fHeight = float.Parse(result.ToString()); //取纯普通板高度
            }
            catch (Exception ex)
            {

                fHeight = 0f;
            }
            return fHeight;

        }
        /// <summary>
        /// 当有切片 板时，计算放完切片 板 还可以放多少普通板子
        /// </summary>
        /// <param name="sFormula">计算工式</param>
        /// <param name="fBookMaxHeight">限高</param>
        /// <param name="fProductThick">板厚</param>
        /// <param name="uCrossPlateNums">切片板数量</param>
        /// <returns></returns>
        private uint GetMaxNormalPiceWhenKnowCrossPies(string sFormula, float fBookMaxHeight, float fProductThick, uint uCrossPlateNums)
        {
            uint uMaxNomalPice = 0;
            try
            {
                string sCalcFormulaWithValue = string.Format(sFormula, fBookMaxHeight, fProductThick, uCrossPlateNums); //板厚 和限高 算普通板最高叠放片数
                object result = new DataTable().Compute(sCalcFormulaWithValue, "");
                int iMaxNomalPice = (int)Math.Floor(float.Parse(result.ToString())); //
                if (iMaxNomalPice < 0)
                {
                    uMaxNomalPice = 0;
                }
                else
                {
                    uMaxNomalPice = (uint)iMaxNomalPice;
                }
            }
            catch (Exception ex)
            {

                uMaxNomalPice = 0;
            }
            string sTempPostUIMsg = string.Format("当前切片:{0};限高:{1}计算最大普通叠片结果值:{2}", uCrossPlateNums, fBookMaxHeight, uMaxNomalPice);
            return uMaxNomalPice;
        }

        private uint GetMaxPiec(string sFormula, float fBookMaxHeight, float fProductThick)
        {
            uint uMaxNomalPice = 0;
            try
            {
                string sCalcFormulaWithValue = string.Format(sFormula, fBookMaxHeight, fProductThick); //板厚 和限高 算普通板最高叠放片数
                object result = new DataTable().Compute(sCalcFormulaWithValue, "");
                int iMaxNomalPice = (int)Math.Floor(float.Parse(result.ToString()));
                if (iMaxNomalPice < 0)
                {
                    uMaxNomalPice = 0;
                }
                else
                {
                    uMaxNomalPice = (uint)iMaxNomalPice;
                }
            }
            catch (Exception)
            {

                uMaxNomalPice = 0;
            }
            string sTempPostUIMsg = string.Format("计算最大叠片结果值:{0}", uMaxNomalPice);
            return uMaxNomalPice;
        }



        private uint GetEachBookCanLoadMaxCrossPlate(float fProductThick, CalcFormula calcMaxCrossFormula, float fBookMaxHigh = 37.5f)
        {
            uint uiMaxLoadCrossPlates = 0;

            return uiMaxLoadCrossPlates;
        }
        /// <summary>
        /// 计算标准板厚度 防止默认值 超高; 
        /// </summary>
        /// <param name="StandPlates">标准板厚度</param>
        /// <param name="fProductThick">产品厚度 mm</param>
        /// <param name="mFormula">叠合公式</param>
        /// <param name="fBookMaxHigh">限高 mm</param>
        /// <returns></returns>
        private uint GetCorrectStandPlates(uint uStandPlates, float fProductThick, CalcFormula mFormula, float fBookMaxHigh = 37.5f)
        {
            uint uInputStandPlates = uStandPlates;
            uint uMaxPiec = GetMaxPiec(mFormula.sAllNormalMaxPiec, fBookMaxHigh, fProductThick);
            if (uMaxPiec > 0 && uMaxPiec < uStandPlates)
            {
                uStandPlates = (uint)uMaxPiec; //若计算出的最大板数<标准板数量 ，则调整标准板数量为 最大板数量
            }
            else if (uMaxPiec == 0)
            {
                uStandPlates = 0;  ///标准板计算异常
            }
            string sTempPostUIMsg = string.Format("输入标准叠合张数:{0};计算叠板最大张数:{1};最终标准张数:{2}", uInputStandPlates, uMaxPiec, uStandPlates);

            return uStandPlates;

        }

        /// <summary>
        /// 计算补钢板
        /// </summary>
        /// <param name="composeBook"></param>
        /// <returns></returns>
        private int CalcSuppleSteelPlateNums(CalcFormula mFormula, float fProductThick, ref CalaSteelPlateUtil composeBook, float fLowerHeight)
        {
            int iRet = -1;
            if (composeBook != null)
            {
                float fHeight = 0f;
                if (composeBook.CrossPlate > 0 && composeBook.CommPlate > 0) //混合板
                {
                    ///求Mix
                    fHeight = GetMixHeight(mFormula.sMixHeight, fProductThick, composeBook.CommPlate, composeBook.CrossPlate);

                }
                else if (composeBook.CrossPlate == 0 && composeBook.CommPlate > 0) //普通板
                {
                    fHeight = GetAllNormalProductHeight(mFormula.sAllNormalHeight, fProductThick, composeBook.CommPlate);
                }

                if (fHeight < fLowerHeight && fHeight > 0)
                {
                    int iSuppleSteelPlate = (int)Math.Ceiling((fLowerHeight - fHeight) / 1.5f);
                    if (iSuppleSteelPlate > 1) //大于1张
                    {
                        uint uDownAddSteelPlate = (uint)(iSuppleSteelPlate / 2);
                        uint uUpAddSteelPlate = (uint)(iSuppleSteelPlate - uDownAddSteelPlate);
                        composeBook.DownSteelPlateNums = uDownAddSteelPlate;
                        composeBook.UpSteelPlateNums = uUpAddSteelPlate;
                    }
                    else if (iSuppleSteelPlate == 1)
                    {
                        composeBook.DownSteelPlateNums++;
                    }
                }
            }
            return iRet;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="uNormalProductNums"></param>
        /// <param name="uEachBookLoadPlateNums"></param>
        /// <returns></returns>
        private int CalcNormalPlateBooks(uint uNormalProductNums, uint uEachBookLoadPlateNums)
        {
            int iRet = -1;
            try
            {
                uint uiCommModLatPlate = uNormalProductNums % uEachBookLoadPlateNums;
                if (uiCommModLatPlate == 0) //板子全部均分
                {
                    BookFullNoCross.BookNums = (uint)(uNormalProductNums / uEachBookLoadPlateNums);//板数 这里除得尽
                    BookFullNoCross.CommPlate = uEachBookLoadPlateNums;//普通板片数

                    BookNoFullNoCross.BookNums = 0;//板数 第二类型
                    BookNoFullNoCross.CommPlate = 0;//普通板片数
                }
                else
                {

                    BookFullNoCross.BookNums = (uint)(uNormalProductNums / uEachBookLoadPlateNums);//板数取整
                    BookFullNoCross.CommPlate = BookFullNoCross.BookNums > 0 ? (uint)Math.Round((double)uNormalProductNums / ((uint)(uNormalProductNums / uEachBookLoadPlateNums) + 1)) : 0;//片数 除不尽 会多一个book

                    BookNoFullNoCross.BookNums = 1;//板数 第二类型
                    BookNoFullNoCross.CommPlate = uNormalProductNums - (BookFullNoCross.BookNums * BookFullNoCross.CommPlate);//剩下的取余数  取余数未满叠合板

                    uint uDiffrens = (uint)Math.Abs((int)BookNoFullNoCross.CommPlate - (int)BookFullNoCross.CommPlate);
                    if (BookFullNoCross.BookNums > 1 && uDiffrens > 1)  ///最后一组与满本差值大于1，需要求整体平均 
                    {

                        if ((BookFullNoCross.CommPlate * (uDiffrens - 1) + BookNoFullNoCross.CommPlate) % uDiffrens == 0) //理论是上没有问题的
                        {
                            BookNoFullNoCross.CommPlate = (BookFullNoCross.CommPlate * (uDiffrens - 1) + BookNoFullNoCross.CommPlate) / uDiffrens;
                            BookNoFullNoCross.BookNums = uDiffrens;
                            BookFullNoCross.BookNums = BookFullNoCross.BookNums - (uDiffrens - 1); //book不会变化
                        }
                        //难证数据是否一致
                    }
                    else if (uDiffrens == 0)
                    {
                        CalcNormalPlateBooks(uNormalProductNums, BookFullNoCross.CommPlate);
                    }


                }
                iRet = 0;
            }
            catch (Exception ex)
            {

                iRet = 0;
            }
            return iRet;

        }
        /// <summary
        /// 
        /// </summary>
        /// <param name="fProductThick">产品厚度 2PP+2铜箔+1基板</param>
        /// <param name="fSteelPlateThick">钢板厚度</param>
        /// <param name="iProductNums">板子总数量 包含切片</param>
        /// <param name="iCrossPlateNums">切片数量</param>
        /// <param name="iStandPlateNums">标准片数 由外面查询获取，查询不到直接默认30张</param>
        /// <param name="iCrashPad"> 缓冲垫使用标识 0 不使用 ,1使用1张 2 使用2张 3 使用3张缓冲垫</param>
        public int CalcBook(float fProductThick, uint iProductNums, uint iCrossPlateNums, string sLayer_Type, uint iStandPlateNums = 30)
        {
            int iRet = -1;
            ///后面加层数校验
            CalcFormula mCalcFormula = null;
            if (sLayer_Type == "LA3")
            {
                sLayer_Type = "LA7";
            }
            iRet = IniSteelInfo(sLayer_Type);
            if (iRet != 0)
            {
                return iRet;
            }
            ///先检查参数是否OK，把所有公式都计算一 IniSteelInfo次///////////////////////////////////
            ///
            if (fProductThick < 0.001f || iProductNums <= 0 || m_DitCalcFormula == null || m_DitCalcFormula.TryGetValue(sLayer_Type, out mCalcFormula) == false || mCalcFormula == null)
            {
                return iRet;
            }

            //  uint iStandPlateNums = GetStandBookPlates(sLayerType); //获取标准板子数量
            uint iEachBookCanLoadCrossPlateNumNoCrash = 0;  //不加缓冲垫 每本可装多少切片
            uint iEachBookCanLoadCrossPlateNumWithCrach = 0;  //加缓冲垫 每本可装多少切片
            uint uiCommModLatPlate = 0;//非切片板子取余后剩下的普通板子
            uint uiCrossModLastPlate = 0;  //切片板取余后剩下的纯切片板子
            int iRemainCommPlate = 0; //普通剩余板
            float fBookMaxHeight = 37.5f; //板高上限  2021年3月16日12:11:3 上海奥特斯
            float fBookMinHeight = 30f;  //板下限
            int iRemainCrossPlate = 0; //切片剩余板
            iStandPlateNums = GetCorrectStandPlates(iStandPlateNums, fProductThick, mCalcFormula, fBookMaxHeight); //
            if (iStandPlateNums > 0 && iStandPlateNums <= 30)
            {
                if (iCrossPlateNums == 0)  //无切片 
                {
                    if (0 == CalcNormalPlateBooks(iProductNums, iStandPlateNums))
                    {
                        if (BookNoFullNoCross.BookNums > 0)
                        {
                            uint iEachBookLoadAvgCommPlate = (uint)Math.Round((double)iProductNums / (double)(BookFullNoCross.BookNums + BookNoFullNoCross.BookNums)); //如果采样数据太多则可能会造成误差
                            //2022-05-24 
                            //CalcNormalPlateBooks(iProductNums, iEachBookLoadAvgCommPlate);

                        }

                    }
                    ///判断是否补钢板
                    /////////////////////////////////
                    //////   CalcSuppleSteelPlatenNums(ref boo)
                    ////////////////////////////////
                }
                else  ///有切片
                {
                    uint uMaxCrossPiec = GetMaxPiec(mCalcFormula.sAllSliceMaxPiec, fBookMaxHeight, fProductThick);
                    if (uMaxCrossPiec > iStandPlateNums)
                    {
                        uMaxCrossPiec = iStandPlateNums; ///基本不可能出现
                    }
                    if ((float)iCrossPlateNums / (float)uMaxCrossPiec >= 1.0f)
                    {
                        BookFullOnlyCross.CrossPlate = uMaxCrossPiec;  //全切片数据
                        BookFullOnlyCross.BookNums = (uint)iCrossPlateNums / uMaxCrossPiec; //全切片数据
                        BookFullOnlyCross.CommPlate = 0;
                    }
                    //并列关系 先处理纯切片板子 好处理
                    if (iCrossPlateNums % uMaxCrossPiec > 0) // 还有未分配的切片 
                    {
                        BookNoFullMixCross.CrossPlate = iCrossPlateNums % uMaxCrossPiec; //剩余切片数量
                        BookNoFullMixCross.CommPlate = GetMaxNormalPiceWhenKnowCrossPies(mCalcFormula.sHaveCrossNumCanLoadMaxNormalPiecNum, fBookMaxHeight, fProductThick, BookNoFullMixCross.CrossPlate);
                        BookNoFullMixCross.BookNums = 1;
                        if ((BookNoFullMixCross.CrossPlate + BookNoFullMixCross.CommPlate) > iStandPlateNums) //防止切片数+普通片数量  > 标准片数量
                        {
                            BookNoFullMixCross.CommPlate = iStandPlateNums - BookNoFullMixCross.CrossPlate; //剩余最大板子数量 ; 这里不再重复check 高度
                        }

                        if (((int)iProductNums - (int)iCrossPlateNums - BookNoFullMixCross.CommPlate) <= 0) //针对底板数量较小的情况
                        {
                            BookNoFullMixCross.CommPlate = iProductNums - iCrossPlateNums;
                        }
                        else
                        {
                            uint iLeftNormalPlateNums = iProductNums - iCrossPlateNums - BookNoFullMixCross.CommPlate; //剩余普通板数量 =所有板-切片板-混装的普通板
                            CalcNormalPlateBooks(iLeftNormalPlateNums, iStandPlateNums);
                            //剩余的板已分好剩下判断
                            //比较切板高度与纯面板高度差多少块普通钢板
                            //第一次分配完成
                            //再判断
                            //获取混装板高度 
                            float fBookNofullMixCrossHeight = GetMixHeight(mCalcFormula.sMixHeight, fProductThick, BookNoFullMixCross.CommPlate, BookNoFullMixCross.CrossPlate);
                            float fGetTotalHeigth = fBookNofullMixCrossHeight + GetAllNormalProductHeight(mCalcFormula.sAllNormalHeight, fProductThick, BookFullNoCross.CommPlate) * BookFullNoCross.BookNums + GetAllNormalProductHeight(mCalcFormula.sAllNormalHeight, fProductThick, BookNoFullNoCross.CommPlate) * BookNoFullNoCross.BookNums;
                            float fAvgHeight = fGetTotalHeigth / (1 + BookFullNoCross.BookNums + BookNoFullNoCross.BookNums); //平均高度;

                            ///混合切片板最终放多少张普通板
                            uint iRecalcCanLoadNormalPlate = GetMaxNormalPiceWhenKnowCrossPies(mCalcFormula.sHaveCrossNumCanLoadMaxNormalPiecNum, fAvgHeight, fProductThick, BookNoFullMixCross.CrossPlate);
                            uint uLeftNormalPlate = iProductNums - iCrossPlateNums - iRecalcCanLoadNormalPlate; ///所有剩余普通板

                            int iMixBookLeftNormalPlate = (int)BookNoFullMixCross.CommPlate - (int)iRecalcCanLoadNormalPlate;  ///混合板 中余出的 普通板还有多少张  用于重新分配算子
                            float fEachAvgBookPlate = (float)uLeftNormalPlate / (BookFullNoCross.BookNums + BookNoFullNoCross.BookNums); //满本和非满本重新分配后 每板平均数是否超了 普通板标准线
                            if (fEachAvgBookPlate >= iStandPlateNums)  //全部挪过去 超高了 多了 不完  普通板整体按最高分 理论上不会
                            {
                                BookNoFullMixCross.CommPlate = iProductNums - iStandPlateNums * (BookFullNoCross.BookNums + BookNoFullNoCross.BookNums) - iCrossPlateNums;  //混合板普通板数量
                                CalcNormalPlateBooks(iStandPlateNums * (BookFullNoCross.BookNums + BookNoFullNoCross.BookNums), iStandPlateNums);
                            }
                            else
                            {
                                //即便把所有的挪过去都够不上 则尽量取余量
                                BookNoFullMixCross.CommPlate = iRecalcCanLoadNormalPlate;  //混合板普通板数量
                                CalcNormalPlateBooks(iProductNums - iRecalcCanLoadNormalPlate - iCrossPlateNums, iStandPlateNums);

                            }
                        }
                    }
                    else
                    {
                        CalcNormalPlateBooks(iProductNums - iCrossPlateNums, iStandPlateNums);
                    }
                }
                ///增加钢板
                CalcSuppleSteelPlateNums(mCalcFormula, fProductThick, ref BookFullNoCross, fBookMinHeight);

                CalcSuppleSteelPlateNums(mCalcFormula, fProductThick, ref BookNoFullNoCross, fBookMinHeight);
                CalcSuppleSteelPlateNums(mCalcFormula, fProductThick, ref BookNoFullMixCross, fBookMinHeight);
                CalcSuppleSteelPlateNums(mCalcFormula, fProductThick, ref BookFullOnlyCross, fBookMinHeight);

            }

            return iRet = 0;
        }


    }
}
